/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.persistence.manager;

import java.util.Collection;

import com.genia.toolbox.persistence.criteria.Criteria;
import com.genia.toolbox.persistence.criteria.criterion.Criterion;
import com.genia.toolbox.persistence.criteria.criterion.Junction;
import com.genia.toolbox.persistence.criteria.enumeration.MatchMode;
import com.genia.toolbox.persistence.criteria.field.Field;
import com.genia.toolbox.persistence.exception.AggregateException;

/**
 * This interface represents the generic <code>RestrictionsManager</code> that
 * allows user to generate restriction to use with criteria.
 */
public interface RestrictionsManager
{

  /**
   * Return a <code>Criterion</code> that always accept.
   * 
   * @return a <code>Criterion</code> that always accept
   */
  public Criterion accept();



  /**
   * Return a criterion that represents the conjunction of two criterion.
   * 
   * @param criterion1
   *          the first criterion
   * @param criterion2
   *          the seconde criterion
   * @return a criterion representation <code> criterion1 && criterion2</code>
   */
  public Criterion and(Criterion criterion1, Criterion criterion2);



  /**
   * Return a criterion that represents a conjunction.
   * 
   * @return a criterion that represents a conjunction
   */
  public Junction conjunction();



  /**
   * Return a <code>Criterion</code> that always deny.
   * 
   * @return a <code>Criterion</code> that always deny
   */
  public Criterion deny();



  /**
   * Return a criterion that represents a disjunction.
   * 
   * @return a criterion that represents a disjunction
   */
  public Junction disjunction();



  /**
   * Return a criterion that represents the equality between two fields. A
   * <code>null</code> field is never equal to any other field.
   * 
   * @param field1
   *          the first field in the equality
   * @param field2
   *          the second field in the equality
   * @return a criterion representing <code>field1.equals(field2)</code>
   */
  public Criterion equals(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is greater or equals to
   * another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 >= field2</code>
   */
  public Criterion greaterOrEquals(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is greater than another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 > field2</code>
   */
  public Criterion greaterThan(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field match (without case)
   * another.
   * 
   * @param field1
   *          the first field in the matching
   * @param field2
   *          the second field in the matching
   * @param matchMode
   *          the type of match
   * @return a criterion representing that <code>field1</code> match (without
   *         case) <code>field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   */
  public Criterion ilike(Field field1, Field field2, MatchMode matchMode)
      throws AggregateException;



  /**
   * Return a criterion that represents that a field is contained in a
   * collection of objects.
   * 
   * @param field
   *          the field to search
   * @param collection
   *          the collection the field must be in
   * @return a criterion representing that <code>field</code> is contained in
   *         <code>collection</code>
   */
  public Criterion isIn(Field field, Collection<?> collection);



  /**
   * Return a criterion that represents that a field is contained is the main
   * result of another query.
   * 
   * @param field
   *          the field to search
   * @param criteria
   *          the second query
   * @return a criterion representing that <code>field</code> is contained in
   *         the main result of <code>criteria</code>
   */
  public Criterion isIn(Field field, Criteria<?> criteria);



  /**
   * Return a criterion that represents that a field is contained in another
   * field (the second field must be a collection).
   * 
   * @param field1
   *          the field to search
   * @param field2
   *          the field to search in
   * @return a criterion representing that <code>field1</code> is contained in
   *         the field <code>field2</code>
   */
  public Criterion isIn(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is not <code>null</code>.
   * 
   * @param field
   *          the field to check
   * @return a criterion that represents that a field is not <code>null</code>
   */
  public Criterion isNotNull(Field field);



  /**
   * Return a criterion that represents that two fields are not the same. That
   * means that the two field are not equals and that the two fields are not
   * <code>null</code>.
   * 
   * @param field1
   *          the first field in the inequality
   * @param field2
   *          the second field in the inequality
   * @return a criterion representing <code>field1 != field2</code>
   */
  public Criterion isNotSame(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is <code>null</code>.
   * 
   * @param field
   *          the field to check
   * @return a criterion that represents that a field is <code>null</code>
   */
  public Criterion isNull(Field field);



  /**
   * Return a criterion that represents that two fields are the same. That means
   * that either the two field are equals, or that the two fields are
   * <code>null</code>.
   * 
   * @param field1
   *          the first field in the equality
   * @param field2
   *          the second field in the equality
   * @return a criterion representing <code>field1 == field2</code>
   */
  public Criterion isSame(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is lesser or equals to
   * another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 <= field2</code>
   */
  public Criterion lesserOrEquals(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is lesser than another.
   * 
   * @param field1
   *          the first field in the comparaison
   * @param field2
   *          the second field in the comparaison
   * @return a criterion representing <code>field1 < field2</code>
   */
  public Criterion lesserThan(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field match another.
   * 
   * @param field1
   *          the first field in the matching
   * @param field2
   *          the second field in the matching
   * @param matchMode
   *          the type of match
   * @return a criterion representing that <code>field1</code> match
   *         <code>field2</code>
   * @throws AggregateException
   *           when there is an error with an aggregate definition
   */
  public Criterion like(Field field1, Field field2, MatchMode matchMode)
      throws AggregateException;



  /**
   * Return a criterion that represents the negation of another criterion.
   * 
   * @param criterion
   *          the critertion to negate
   * @return a criterion representing the negation of <code>criterion</code>
   */
  public Criterion not(Criterion criterion);



  /**
   * Return a criterion that represents the inequality between two fields. A
   * <code>null</code> field is never equal to any other field.
   * 
   * @param field1
   *          the first field in the inequality
   * @param field2
   *          the second field in the inequality
   * @return a criterion representing <code>!field1.equals(field2)</code>
   */
  public Criterion notEquals(Field field1, Field field2);



  /**
   * Return a criterion that represents that a field is not contained in a
   * collection of objects.
   * 
   * @param field
   *          the field to search
   * @param collection
   *          the collection the field must not be in
   * @return a criterion representing that <code>field</code> is not contained
   *         in <code>collection</code>
   */
  public Criterion notIn(Field field, Collection<?> collection);



  /**
   * Return a criterion that represents that a field is not contained is the
   * main result of another query.
   * 
   * @param field
   *          the field to search
   * @param criteria
   *          the second query
   * @return a criterion representing that <code>field</code> is not contained
   *         in the main result of <code>criteria</code>
   */
  public Criterion notIn(Field field, Criteria<?> criteria);



  /**
   * Return a criterion that represents that a field is not contained in another
   * field (the second field must be a collection).
   * 
   * @param field1
   *          the field to search
   * @param field2
   *          the field to search in
   * @return a criterion representing that <code>field1</code> is not
   *         contained in the field <code>field2</code>
   */
  public Criterion notIn(Field field1, Field field2);



  /**
   * Return a criterion that represents the disjunction of two criterion.
   * 
   * @param criterion1
   *          the first criterion
   * @param criterion2
   *          the seconde criterion
   * @return a criterion representation <code> criterion1 || criterion2</code>
   */
  public Criterion or(Criterion criterion1, Criterion criterion2); // NOPMD
}
